package com.app.Controller;

import java.io.File;
import java.util.ArrayList;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.UserDataHandler;

import com.app.DTO.RoleDTO;
import com.app.PhanQuyen.Quyen;

import ReadWriteXML.CMember;
import ReadWriteXML.CNeighbor;
import ReadWriteXML.DOMUltil;
import ReadWriteXML.ReadXML;
import ReadWriteXML.WriteXML;
import android.os.Environment;
import android.util.Log;

public class ReadWriteFileController {
	final private static String SEPARATOR = "/";
	final private static String SEPARATOR1 = "##";
	private static String _fNameListGroup = "ListGroupJoin.txt";
	public static String DIRECTORY = Environment.getExternalStorageDirectory().toString() + "/";
	public static String DIRECTORYMES = DIRECTORY + "MES/";
	public static String DIRECTORYCHAT = DIRECTORY + "MES/CHAT/";
	public static String DIRECTORYCHATPEER = DIRECTORY + "MES/CHAT/PEER/";
	public static String DIRECTORYCHATGROUP = DIRECTORY+ "MES/CHAT/GROUP/";
	public static String DIRECTORYTEST = DIRECTORY + "MES/TEST/";
	public static String DIRECTORYTESTCONTENT = DIRECTORY + "MES/TEST/CONTENT/";

	public static String pathNeighborsList = DIRECTORY + "NeighborsList.xml";
	
	public static String RULE_BASE_PATH=DIRECTORY+"ListRule.xml";
	public static String MY_ROLE_PATH=DIRECTORY+"myRole.xml";
	public static String ROLE_SETTING_PATH=DIRECTORY+"mySettingRole.xml";
	public static String ROLE_DEFAULT_PATH=DIRECTORY+"roleMacDinh.xml";
	public static String MEMBER_PATH=DIRECTORY+"memberList.xml";
		public static boolean deleteFile(String path) {
		File f1 = new File(path);
		boolean success = f1.delete();
		if (!success) {
			System.out.println("Deletion failed.");
		} else {
			System.out.println("File deleted.");
		}
		return success;
	}

	public static boolean isFile(String path) {
		File f = new File(path);
		return f.exists();
	}
	
	/**
	 * Phú
	 * Đọc danh sách Quyền từ file
	 * @param path : Đường dẫn tới file
	 * @return ArrayList<Quyen>
	 */
	
	public static ArrayList<Quyen> readRule(String path) {
		ArrayList<Quyen> rs = null;

		Document doc = ReadXML.BuildXML(path);

		if (doc != null) {
			rs = new ArrayList<Quyen>();
			NodeList nodeList = doc.getElementsByTagName("rule");
			int n = nodeList.getLength();
			for (int i = 0; i < n; i++) {
				Element e = (Element) nodeList.item(i);
				
				boolean read = Boolean.parseBoolean(e
						.getElementsByTagName("read").item(0).getChildNodes()
						.item(0).getNodeValue());

				boolean write = Boolean.parseBoolean(e
						.getElementsByTagName("write").item(0).getChildNodes()
						.item(0).getNodeValue());
				boolean send = Boolean.parseBoolean(e
						.getElementsByTagName("send").item(0).getChildNodes()
						.item(0).getNodeValue());
				boolean receive = Boolean.parseBoolean(e
						.getElementsByTagName("receive").item(0)
						.getChildNodes().item(0).getNodeValue());

				Quyen quyen = new Quyen(read, write, send, receive,e.getAttribute("ID"),e.getAttribute("Name"));
				rs.add(quyen);

			}
		}

		return rs;
	}
/**
 * Phú
 * Đọc danh sách vai trò từ file
 * @param path : Đường dẫn tới file
 * @return ArrayList<RoleDTO>
 */
	public static ArrayList<RoleDTO> readRole(String path) {
		ArrayList<RoleDTO> rs = null;

		Document doc = ReadXML.BuildXML(path);

		if (doc != null) {
			
			rs = new ArrayList<RoleDTO>();
			NodeList roleList = doc.getElementsByTagName("Role");
			int n = roleList.getLength();
			
			for (int i = 0; i < n; i++) {
				Element element = (Element) roleList.item(i);
				RoleDTO role = new RoleDTO();
				role.setName(element.getAttribute("Name"));
				
				NodeList ruleList = element.getElementsByTagName("Rule");

				int m = ruleList.getLength();

				for (int j = 0; j < m; j++) {
					Element e = (Element) ruleList.item(j);

					boolean read = Boolean.parseBoolean(e
							.getElementsByTagName("read").item(0)
							.getChildNodes().item(0).getNodeValue());

					boolean write = Boolean.parseBoolean(e
							.getElementsByTagName("write").item(0)
							.getChildNodes().item(0).getNodeValue());
					boolean send = Boolean.parseBoolean(e
							.getElementsByTagName("send").item(0)
							.getChildNodes().item(0).getNodeValue());
					boolean receive = Boolean.parseBoolean(e
							.getElementsByTagName("receive").item(0)
							.getChildNodes().item(0).getNodeValue());

					Quyen rule = new Quyen(read, write, send, receive,
							e.getAttribute("ID"), e.getAttribute("Name"));
					role.addRule(rule);
				
				}
				rs.add(role);
			}
		}

		return rs;
	}
	/**
	 * Phú
	 * Tạo node XML từ 1 quyền
	 * @param doc : Document
	 * @param rule: Quyền
	 * @return Node
	 */
	private static Node createRuleNode(Document doc,Quyen rule){

		Element e=doc.createElement("Rule");
		e.setAttribute("ID", rule.getID());
		e.setAttribute("Name", rule.getName());
		
		Node read=doc.createElement("read");
		Node write=doc.createElement("write");
		Node send=doc.createElement("send");
		Node receive=doc.createElement("receive");
		
		
		read.setTextContent(rule.getRead().toString());
		write.setTextContent(rule.getWrite().toString());
		send.setTextContent(rule.getSend().toString());
		receive.setTextContent(rule.getReceive().toString());
		
		e.appendChild(read);
		e.appendChild(write);
		e.appendChild(send);
		e.appendChild(receive);
		
		return (Node)e;
	}
	/**
	 * Tạo Node XML từ 1 RoleDTO (Vai trò)
	 * @param doc :Document
	 * @param role :Vai trò
	 * @return Node
	 */
	private static Node createRoleNode(Document doc, RoleDTO role){
		Element e=doc.createElement("Role");
		e.setAttribute("ID", role.getName());
		e.setAttribute("Name", role.getName());
		int n=role.getRuleList().size();
		
		for(int i=0;i<n;i++){
			e.appendChild(createRuleNode(doc, role.getRuleList().get(i)));
		}
		return (Node)e;
		
	}
	/**
	 * Phú
	 * Ghi danh sách Vai trò (RoleDTO) xuống file XML
	 * @param path : Đường dẫn
	 * @param roleList : Danh sách vai trò
	 */
	public static void writeRole(String path, ArrayList<RoleDTO> roleList){
		if(isFile(path))
			deleteFile(path);
		Document doc=null;
		doc=WriteXML.insertRoot(doc, path, "RoleList");
		
		Log.d("Phu","root =null"+	(doc.getFirstChild()==null));
		for(int i=0;i<roleList.size();i++){
			doc.getFirstChild().appendChild(createRoleNode(doc, roleList.get(i)));
		}
		DOMUltil.writeXmlToFile(path, doc);
		if(isFile(path))
			Log.d("Phu","da ghi");
		else
			Log.d("Phu","chua ghi"+path);
	}

	/**
	 * Insert 1 vai trò vào 1 file XML có sẵn. Nếu file ko tồn tại thì tạo file mới
	 * @param path : Đường dẫn
	 * @param role : Vai trò
	 */
	public static void insertRole(String path, RoleDTO role){
		if(isFile(path)){
			Document doc=ReadXML.BuildXML(path);
			doc.getFirstChild().appendChild(createRoleNode(doc, role));
			DOMUltil.writeXmlToFile(path, doc);
		}else{
			ArrayList<RoleDTO> roleList=new ArrayList<RoleDTO>();
			roleList.add(role);
			writeRole(path, roleList);
		}
	}
	/**
	 * Phú
	 * Cập nhật 1 vai trò trong 1 file xml có sẵn (dựa vào tên vai trò)
	 * @param path : Đường dẫn
	 * @param oldRole : Vai trò cần cập nhật
	 * @param newRole : Vai trò mới
	 */
	public static void updateRole(String path, RoleDTO oldRole, RoleDTO newRole){
		Log.d("Phu","oooo:"+oldRole.getRuleList().size()+newRole.getRuleList().size());
		Document doc=null;
		doc=DOMUltil.parse(path);
		Log.d("Phu","doc "+((Node)doc.getElementsByTagName("Role").item(0)).getChildNodes().getLength());
		NodeList listRole=doc.getElementsByTagName("Role");
		
		int n=listRole.getLength();
		for(int i=0;i<n;i++){
			Element e=(Element)listRole.item(i);
			
			if(e.getAttribute("Name").equals(oldRole.getName())){
				
				e.getParentNode().removeChild(e);
				Log.d("Phu","doc 1"+doc.getElementsByTagName("Role").getLength());
				doc.getFirstChild().appendChild(createRoleNode(doc, newRole));
				Log.d("Phu","doc 2"+((Node)doc.getElementsByTagName("Role").item(0)).getChildNodes().getLength());
				break;
			}
		}
		DOMUltil.writeXmlToFile(path, doc);
	}
	
	/**
	 * Xóa 1 Vai trò trong 1 file XML
	 * @param path : Đường dẫn
	 * @param role: Vai trò cần xóa
	 */
	public static void deleteRole(String path, RoleDTO role){
		
		Document doc=null;
		doc=DOMUltil.parse(path);		
		NodeList listRole=doc.getElementsByTagName("Role");		
		int n=listRole.getLength();
		for(int i=0;i<n;i++){
			Element e=(Element)listRole.item(i);			
			if(e.getAttribute("Name").equals(role.getName())){				
				e.getParentNode().removeChild(e);				
				break;
			}
		}
		DOMUltil.writeXmlToFile(path, doc);
	}
	
	public static ArrayList<CNeighbor> readNeighbor() {
		ArrayList<CNeighbor> listNeighbor = new ArrayList<CNeighbor>();
		ArrayList<CMember> listMember = new ArrayList<CMember>();
		Document _doc = ReadXML.BuildXML(ReadWriteFileController.pathNeighborsList);
		Log.d("PEERDROID","pathNeighborsList: " + ReadWriteFileController.pathNeighborsList);
		listMember = ReadXML.ReadMember(_doc);
		boolean temp=false;

		for(int i=0;i<listMember.size();i++){
			CMember mem = new CMember();
			mem=listMember.get(i);
			CNeighbor neighbor=new CNeighbor(mem, temp);
			listNeighbor.add(neighbor);
		}
		return listNeighbor;

	}
	
	public static ArrayList<CMember> readMember(String path){
		return ReadXML.ReadMember(path);
	}
	/**
	 * Phú
	 * Ghi danh sách thành viên xuống file
	 * @param path
	 * @param memberList
	 */
	public static void writeMember(String path, ArrayList<CMember> memberList){
		Document doc=null;
		doc = WriteXML.insertRoot(doc, path, "ListLearner");		
		for (int i = 0; i < memberList.size(); i++) {
			doc.getFirstChild().appendChild(createMemberNode(doc, memberList.get(i)));			
		}
		DOMUltil.writeXmlToFile(path, doc);
	}
	/**
	 * Phú
	 * Insert 1 member xuống file.(Nếu file ko tồn tại thì tạo mới)
	 * Nếu member đã tồn tại thì ko insert
	 * @param path
	 * @param member
	 */
	public static void insertMember(String path,CMember member){
		if(isFile(path)){
			ArrayList<CMember> memberList=readMember(path);
			for(CMember m:memberList){
				if(m.get_userName().equals(member.get_userName()))
					return;
			}
			Document doc=ReadXML.BuildXML(path);
			doc.getFirstChild().appendChild(createMemberNode(doc, member));
			DOMUltil.writeXmlToFile(path, doc);
		}else{
			ArrayList<CMember> memberList=new ArrayList<CMember>();
			memberList.add(member);
			writeMember(path, memberList);
		}
	}
	/**
	 * Phú
	 * Xóa 1 member trong file XML dựa vào user name
	 * @param path
	 * @param member
	 */
	public static void deleteMember(String path,CMember member){
		Document doc=null;
		doc=DOMUltil.parse(path);		
		NodeList listMember=doc.getElementsByTagName("ListLearner");		
		int n=listMember.getLength();
		for(int i=0;i<n;i++){
			Element e=(Element)listMember.item(i);			
			if(e.getAttribute("UserName").equals(member.get_userName())){				
				e.getParentNode().removeChild(e);				
				break;
			}
		}
		DOMUltil.writeXmlToFile(path, doc);
	}
	private static Node createMemberNode(Document doc, CMember member){
		Element e=doc.createElement("Learner");
		e.setAttribute("UserName", member.get_userName());
		
		
		Node ip=doc.createElement("IP");
		Node fullName=doc.createElement("FullName");
		
		
		ip.setTextContent(member.get_ip());
		fullName.setTextContent(member.get_fullName());
		
		
		e.appendChild(ip);
		e.appendChild(fullName);
		
		
		return (Node)e;
	}
}
